

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;


public class Gen1 extends ImageStack{
	//static String slash="/";//mac
		//windows
		static String slash ="\\";
	static final int INITIAL_SIZE = 100;
	String path, basename, basetime, endtime,xOverlap, yOverlap;
	int nSlices,dur, currentT,currentCh;
	String[] names;
	public static File folder;
	public int xStart, yStart, xEnd, yEnd, xWidth, yHeight,zDepth, fuseMode;
	public ArrayList<String> channelList;
	ImageStack currentStack;
	public Gen1(){
		
	}
	public Gen1(int xE, int yE, int width, int height, int z, ArrayList<String> cL, File path,String bname, String btime, String etime){
		currentT =-1;
		folder = path;
		xWidth = width;
		yHeight =height;
		xStart = 0;
		yStart = 0;
		xEnd = xE;
		yEnd = yE;
		zDepth =z;
		nSlices =z;
		fuseMode = 0;
		xOverlap = "0";
		yOverlap ="0";
		basename = bname;
		basetime = btime;
		endtime =etime;
		dur = (Integer.parseInt(endtime)-Integer.parseInt(basetime))+1;
		channelList= cL;		
		this.path = path.getName();
	}
	public ImageProcessor getProcessor(int n) {
		int zSlicer = ((n-1)%(channelList.size()*zDepth))/channelList.size();
		int chSlicer = ((n-1)%(channelList.size()*zDepth))%channelList.size();
		int tSlicer = (n-1)/(channelList.size()*zDepth);
	 	String pathOpened="";	
		ImagePlus toAdd;		
		ImageProcessor toAddProcessor, ip;
		File tempFile;					
		float[] ipPixels, grabber;
		ipPixels= new float[xEnd*xWidth*yEnd*yHeight];
		for(int xPos=xStart; xPos<xEnd;xPos++){
			for(int yPos = yStart; yPos<yEnd;yPos++){
				int posSlicer = (yEnd*xPos)+yPos+1;	
				int timePt = tSlicer+ Integer.parseInt(basetime);
				tempFile = new File(folder.getAbsolutePath()+slash+basename+"_"+channelList.get(chSlicer)+"_s"+posSlicer+"_t"+timePt+".tif");
				if( tempFile.exists()){ 
					pathOpened = folder.getAbsolutePath()+slash+basename+"_"+channelList.get(chSlicer)+"_s"+posSlicer+"_t"+timePt+".tif";							
					toAdd = IJ.openImage(pathOpened,zSlicer+1);
					toAddProcessor = toAdd.getProcessor().toFloat(0,null);
					grabber = (float[])toAddProcessor.getPixels();
					for(int y=0; y<yHeight; y++){
						for (int x=0; x<xWidth; x++){
							ipPixels[(y*yEnd*xWidth+(x+(yPos*xWidth)))+(xPos*yHeight*xWidth*yEnd)] = grabber[y*xWidth+x];
						}
					}
				}else{
					IJ.log(folder.getAbsolutePath()+slash+basename+"_"+channelList.get(chSlicer)+"_s"+posSlicer+"_t"+timePt+".tif"+ " does not exist");			
					Arrays.fill(ipPixels, (float)0);
				}
			}
		}
		ip = new FloatProcessor(xWidth*xEnd,yHeight*yEnd);		
		ip.setPixels(ipPixels);
		return ip;
		
	}
	
	public Object getPixels(int n) {
		//System.gc();
		ImageProcessor ip = getProcessor(n);
		if (ip!=null)
			return ip.getPixels();
		else
			return null;
	}		
	
	public float fuse(float val1, float val2){
 		float fused=val2;
 		switch(fuseMode){
 			case 0://add
 				fused = (float)(val1+val2);
 				break;	
 			case 1: 	//max	
 				if (val1>val2){
 					fused = val1;	
 				}
				break;
			case 2://NEEDTOFIX!!!!!!!!!! HOW?
				if(val1!=0){
					fused = (float)((val1+val2)/2);
				}
				break;
 		}	
 		return fused;
 	}
	public int getSize() {
		return nSlices*channelList.size()*dur;
	}
	
	/** Returns the file name of the Nth image. */
	public String getSliceLabel(int n) {
		 return "";
	}
	
	/** Returns null. */
	public Object[] getImageArray() {
		return null;
	}

   /** Does nothing. */
	public void setSliceLabel(String label, int n) {
	}

	/** Always return true. */
	public boolean isVirtual() {
		return true;
	}

   /** Does nothing. */
	public void trim() {
	}
	public int getWidth(){
		return xWidth;	
	}
	public int getHeight(){
		return yHeight;
	}
	public int getNFrames(){
		return dur;
	}

	public ImageStack getImageStack(){
		return this;
	}
	public void setPixels(Object pixels, int n) {
	}
}
